package bot;

import java.util.Random;

import common.CCard29;
import common.CMessage29.GameState29;
import common.CMessage29.NextJobTypes;

import client.*;

public class CBotBasic extends Thread {
	C29Client o_client;
	C29ClientData o_clientdata;
	int iSeat;
	boolean b_running;
	Random r;
	public CBotBasic(String sServer, int iPort, int iSeat){
		String name = "AI " + Integer.toString(iSeat);
		o_client = new C29Client(name,sServer,iPort);
		o_clientdata = (C29ClientData) o_client.o_clientdata;
		b_running = false;
		this.iSeat = iSeat;
		r = new Random();
	}
	protected void EraseGameHistory(){};
	protected void RememberLastBid(){};
	protected void RememberBidCompletionInfo(){};
	protected void RememberDoubleRedoubleCall(){};
	protected void RememberSingleHandCall(){};
	protected void RememberLastPlay(){};
	protected void RememberHandWinnerInfo(){};
	protected void RememberGameCompletionInfo(){};

	protected int DecideBid(){
		if(r.nextBoolean())
			return 0;
		else
			return 18;
	}
	protected int DecideTrump(){
		return (r.nextInt(6));
	}
	protected int DecideDoubleRedouble(){
		return r.nextInt(3);
	}
	protected int DecideSingleHand(){
		if(r.nextInt(15)==0)
			return 0;
		else
			return 1;
	}
	
	//return Integer 1 to Show Trump, 2 to Show Pair, otherwise CCard29 for normal play
	protected Object DecidePlay(){
		int rand = r.nextInt(6);
		if(rand==0)
			return (new Integer(1));
		else if(rand==1)
			return (new Integer(2));
		else{
			rand = r.nextInt(o_clientdata.GetMyCards().size());
			return o_clientdata.GetMyCards().get(rand);
		}
	}
	@Override
	public void run(){
		o_client.start();
		b_running = true;
		while(b_running){
			try {
				o_clientdata.await();
				if(o_clientdata.GetClientId() == -1){
					b_running = false;
					System.err.println("CBotBasic::Something went wrong");
					break;
				}
				if(o_clientdata.GetSeatForId(o_clientdata.GetClientId()) == -1){
					System.out.println("CBotBasic::Client id " + o_clientdata.GetClientId() + "Seat Requesting :" + iSeat);
					o_client.SendSeatReq(iSeat);
					continue;
				}
				if(!o_clientdata.GetReadyNess(o_clientdata.GetClientId())){
					EraseGameHistory();
					o_client.SendReady();
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.BIDDING){
					RememberLastBid();
					if(o_clientdata.GetNextJobs()[o_clientdata.GetClientId()] == NextJobTypes.BID)
						o_client.SendBid(DecideBid());
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.SETTING_TRUMP){
					RememberBidCompletionInfo();
					if(o_clientdata.GetNextJobs()[o_clientdata.GetClientId()] == NextJobTypes.SET_TRUMP)
						o_client.SetTrump(DecideTrump());
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.WAITING_4_OK2){
					RememberDoubleRedoubleCall();
					if(o_clientdata.GetNextJobs()[o_clientdata.GetClientId()] == NextJobTypes.GET_READY2)
						o_client.SendReady2(DecideDoubleRedouble());
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.WAITING_4_OK3){
					RememberSingleHandCall();
					if(o_clientdata.GetNextJobs()[o_clientdata.GetClientId()] == NextJobTypes.GET_READY3)
						o_client.SendReady3(DecideSingleHand());
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.PLAYING){
					RememberLastPlay();
					if(o_clientdata.GetNextJobs()[o_clientdata.GetClientId()] == NextJobTypes.PLAY){
						Object play = DecidePlay();
						try{
							CCard29 card = (CCard29)play;
							o_client.SendCardPlay(card);
						}
						catch(ClassCastException e){
							if(((Integer)play).intValue() == 1)
								o_client.SendShowTrump();
							if(((Integer)play).intValue() == 2)
								o_client.SendShowPair();
						}
					}
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.PLAY_PAUSED){
					RememberHandWinnerInfo();
					continue;
				}
				if(o_clientdata.GetGameState() == GameState29.PLAY_FIN){
					RememberGameCompletionInfo();
				}
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void abort(){
		b_running = false;
		o_clientdata.signal();
		o_client.abort();
	}
}
